/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.classdiagram.parsers.texteditor.portlabel;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.Collection;
import java.util.Vector;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.uml2.uml.Port;

import antlr.RecognitionException;
import antlr.TokenStreamException;

import com.cea.papyrus.classdiagram.parsers.antlr.PortLabelLexer;
import com.cea.papyrus.classdiagram.parsers.antlr.PortLabelParser;
import com.cea.papyrus.classdiagram.parsers.texteditor.LabelCompletionProcessor;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.MultiplicityCompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.NameCompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.TypeCompletionProposalComputer;

/**
 * Completion processor for action language. <BR>
 * Main class to process the different completions given by the texteditor to
 * its user
 * 
 * @author Remi SCHNEKENBURGER
 * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor
 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor
 * @see com.cea.actionlanguage.sharedresources.texteditor.IPortLabelKeywords
 */
public class PortLabelCompletionProcessor extends LabelCompletionProcessor implements IPortContext {

	/**
	 * 
	 */
	protected Port port;
	
	/**
	 * 
	 * 
	 * @param port 
	 */
	public PortLabelCompletionProcessor(Port port) {
		super();
		this.port = port;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.classdiagram.parsers.texteditor.LabelCompletionProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
	 */
	/**
	 * 
	 * 
	 * @param viewer 
	 * @param documentOffset 
	 * 
	 * @return 
	 */
	@Override
	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
			int documentOffset) {
		String text;
		String prefix = "";
		PortLabelLexer lexer = null;
		PortLabelParser parser = null;
		Collection<ICompletionProposal> result = null;
		int selectionRange = 0;

		try {
			text = viewer.getDocument().get(0, documentOffset);
			lexer = new PortLabelLexer(new BufferedReader(new StringReader(
					text)));
			parser = new PortLabelParser(lexer, port);
			parser.setValidation(true);
			selectionRange = viewer.getSelectedRange().y;
			parser.label();
			modifiersUsed = parser.getModifiersUsed();
			result = computeCompletions(viewer, parser.getContext(),
					documentOffset, selectionRange);
		} catch (BadLocationException e) {
			e.printStackTrace();
		} catch (RecognitionException e) {
			// e.printStackTrace();
			modifiersUsed = parser.getModifiersUsed();
			prefix = getPrefix(viewer, documentOffset);
			result = computeCompletions(viewer, parser.getContext(),
					documentOffset, selectionRange);
		} catch (TokenStreamException e) {
			modifiersUsed = parser.getModifiersUsed();
			prefix = getPrefix(viewer, documentOffset);
			result = computeCompletions(viewer, parser.getContext(),
					documentOffset, selectionRange);
		}

		return result.toArray(new ICompletionProposal[] {});
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.classdiagram.parsers.texteditor.LabelCompletionProcessor#computeCompletions(org.eclipse.jface.text.ITextViewer, int, int, int)
	 */
	/**
	 * 
	 * 
	 * @param viewer 
	 * @param selectionRange 
	 * @param context 
	 * @param documentOffset 
	 * 
	 * @return 
	 */
	@Override
	public Collection<ICompletionProposal> computeCompletions(
			ITextViewer viewer, int context, int documentOffset,
			int selectionRange) {
		Vector<ICompletionProposal> v = new Vector<ICompletionProposal>();
		
		String prefix = getPrefix(viewer, documentOffset);
		switch (context) {
		// DEFAULT : name
		case IPortContext.DEFAULT:
			v.addAll(new NameCompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;

			// NAME: either ':' or ": <Undefined>"
		case IPortContext.NAME:
			v.addAll(createCompletionProposalsWithDifferentName(new String[] {": ", ": <Undefined>" }, new String[] { "Port type", "Undefined port type" }, new String[] {": <Type Name>", ": <Undefined>" }, "", documentOffset));
			break;

			// PORT TYPE (after ":") model types or undefined
		case IPortContext.AFTER_COLON:
			// specific prefix for type... ('<' possible at the beginning)
			prefix = getPrefixForType(viewer, documentOffset);
			// generate completion for Type
			TypeCompletionProposalComputer computer = new TypeCompletionProposalComputer();
			computer.setElement(new com.cea.papyrus.umlutils.Element(port));
			v.addAll(computer.generateCompletionProposals(documentOffset,
					selectionRange, prefix));
			break;

			// MULTIPLICITY: multiplicity or default value or port modifiers
		case IPortContext.TYPE:
			v.addAll(new MultiplicityCompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;

			// nothing after multiplicity
		case IPortContext.MULTIPLICITY:
			break;


			// IN_MULTIPLICITY(after '['): does nothing
		case IPortContext.IN_MULTIPLICITY:
			prefix = getPrefixForMultiplicity(viewer, documentOffset);
			v.addAll(new MultiplicityCompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;

		default:
			break;
		}

		return v;
	}
}